import wx
import sys
from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
from vtk import vtkInteractorStyleTrackballCamera
import wx.lib.mixins.listctrl  as  listmix

##  Subpanel of VisualizationPanel in which the playback of previously recorded movements can be played.
#   Functions such as pausing and stopping and importing a recording are possible as well.
class PlaybackPanel(wx.Panel):

    ##  The constructor of PlaybackPanel. GUI elements of the panel are setup here.
    #   @param[in]  parent  The wx window parent (VisualizationState) of this panel.
    #   @param[in]  state   PlaybackState instance attached to this panel.
    def __init__(self, parent, state):
        wx.Panel.__init__(self, parent)
        ##  The wx window parent (VisualizationState) of this panel.
        self.parent = parent
        ##  The name of this notebook panel.
        self.name = "Playback"
        ##  PlaybackState instance attached to this panel.
        self.__state = state
        self.__state.panel = self

        ##  Split window between the 3D model and the list.
        self.splitterWindow = wx.SplitterWindow(self, -1, style=wx.SP_3D|wx.SP_BORDER)
        recordingListWindow = wx.Panel(self.splitterWindow, -1)
        visWindow = wx.Panel(self.splitterWindow, -1)

        ##  wxVTKRenderWindowInteractor used to show the 3D model.
        self.widget = wxVTKRenderWindowInteractor(visWindow, -1)
        self.widget.SetInteractorStyle(vtkInteractorStyleTrackballCamera())
        self.widget.GetRenderWindow().AddRenderer(self.__state.ren)
        if self.__state.main.Smooth3DModel:
            self.widget.GetRenderWindow().SetAAFrames(3)

        recordingListStaticBox = wx.StaticBox(recordingListWindow, -1, "Recordings")
        ##  Rewind by one frame.
        self.backwardButton = wx.BitmapButton(visWindow, -1, wx.Bitmap("Images/Backward.png", wx.BITMAP_TYPE_PNG))
        ##  The time slider indicating progress of the playback.
        self.slider = wx.Slider(visWindow, -1, 0, 0, 0)
        ##  Forward by one frame.
        self.forwardButton = wx.BitmapButton(visWindow, -1, wx.Bitmap("Images/Forward.png", wx.BITMAP_TYPE_PNG))
        ##  Start playback.
        self.playPauseButton = wx.BitmapButton(visWindow, -1, wx.Bitmap("Images/Play.png", wx.BITMAP_TYPE_PNG))
        spacing = wx.Panel(visWindow, -1)
        ##  Stop playback.
        self.stopButton = wx.BitmapButton(visWindow, -1, wx.Bitmap("Images/Stop.png", wx.BITMAP_TYPE_PNG))
        ## Reset Camera button.
        self.resetCamButton = wx.Button(visWindow, -1, "Reset Camera")

        ##  The list containing all imported/newly created recording.
        self.recordingList = wx.ListBox(recordingListWindow, style=wx.LB_HSCROLL)
        ##  Delete a recording from the list.
        self.deleteButton = wx.Button(recordingListWindow, -1, "Delete")
        ##  Rename a recording in the list.
        self.renameButton = wx.Button(recordingListWindow, -1, "Rename")
        ##  Import a recording to the list.
        self.importButton = wx.Button(recordingListWindow, -1, "Import")

        # Set properties.
        self.widget.SetSize(self.widget.GetBestSize())
        self.backwardButton.SetMinSize((75, 25))
        self.forwardButton.SetMinSize((75, 25))
        self.playPauseButton.SetMinSize((75, 23))
        self.stopButton.SetMinSize((75, 25))

        # Set sizers.
        recordingSizer = wx.BoxSizer(wx.HORIZONTAL)
        recordingListSizer = wx.BoxSizer(wx.VERTICAL)
        recordingListStaticBoxSizer = wx.StaticBoxSizer(recordingListStaticBox, wx.HORIZONTAL)

        listButtonSizer = wx.FlexGridSizer(4,1,10,0)
        visGrid = wx.FlexGridSizer(3, 1, 10, 0)
        player_grid_sizer = wx.FlexGridSizer(2, 4, 10, 20)

        visGrid.Add(self.widget, 0, wx.ALL|wx.EXPAND, 10)
        player_grid_sizer.Add(self.backwardButton, 0, wx.LEFT, 10)
        player_grid_sizer.Add(self.slider, 0, wx.EXPAND, 0)
        player_grid_sizer.Add(self.forwardButton, 0, wx.RIGHT|wx.ALIGN_RIGHT, 10)

        player_grid_sizer.Add(self.playPauseButton, 0, wx.LEFT|wx.BOTTOM, 10)
        player_grid_sizer.Add(spacing, 0, wx.EXPAND, 0)
        player_grid_sizer.Add(self.stopButton, 0, wx.RIGHT|wx.ALIGN_RIGHT, 10)

        player_grid_sizer.Add(self.resetCamButton, 0, wx.LEFT|wx.BOTTOM, 10)
        player_grid_sizer.AddGrowableCol(1)

        visGrid.Add(player_grid_sizer, 1, wx.EXPAND, 0)
        visWindow.SetSizer(visGrid)
        visGrid.AddGrowableRow(0)
        visGrid.AddGrowableCol(0)
        listButtonSizer.Add(self.recordingList, 1, wx.EXPAND, 0)
        listButtonSizer.Add(self.renameButton, 1, wx.EXPAND)
        listButtonSizer.Add(self.deleteButton, 1, wx.EXPAND)
        listButtonSizer.Add(self.importButton, 1, wx.EXPAND)

        listButtonSizer.AddGrowableRow(0)
        listButtonSizer.AddGrowableCol(0)
        recordingListStaticBoxSizer.Add(listButtonSizer, 1, wx.ALL|wx.EXPAND, 10)
        recordingListSizer.Add(recordingListStaticBoxSizer, 1, wx.ALL|wx.EXPAND, 10)
        recordingListWindow.SetSizer(recordingListSizer)
        self.splitterWindow.SplitVertically(visWindow, recordingListWindow, 624)
        self.splitterWindow.SetMinimumPaneSize(5)
        recordingSizer.Add(self.splitterWindow, 1, wx.EXPAND, 0)
        self.SetSizer(recordingSizer)
        self.Layout()

        # Bind events.
        self.Bind(wx.EVT_BUTTON, self.OnTogglePlayPause, self.playPauseButton)
        self.Bind(wx.EVT_BUTTON, self.__state.OnStop, self.stopButton)
        self.Bind(wx.EVT_BUTTON, self.__state.OnBackward, self.backwardButton)
        self.Bind(wx.EVT_BUTTON, self.__state.OnForward, self.forwardButton)
        self.Bind(wx.EVT_BUTTON, self.__state.OnDelete, self.deleteButton)
        self.Bind(wx.EVT_BUTTON, self.__state.OnRename, self.renameButton)
        self.Bind(wx.EVT_BUTTON, self.__state.OnImport, self.importButton)
        self.Bind(wx.EVT_BUTTON, self.OnResetCam, self.resetCamButton)

        self.Bind(wx.EVT_SLIDER, self.__state.OnSlide, self.slider)
        self.Bind(wx.EVT_LISTBOX, self.__state.OnItemSelected, self.recordingList)
        self.Bind(wx.EVT_SIZE, self.OnSize)

        self.DisableFunctions()

    ##  Sets the new tracking bar position so visual feedback during dragging will represent that change that will actually take place.
    def OnSize(self, event):
        self.splitterWindow.SetSashPosition(event.GetSize()[0]-250)
        self.Layout()

    ##  Event Handler for clicking the play/pause button.
    def OnTogglePlayPause(self, event):
        if self.__state.selectedRecording != None:
            if self.__state.PLAYING:
                self.playPauseButton.SetBitmapLabel(wx.Bitmap(self.__state.main.config.root+"\\Images\\Play.png", wx.BITMAP_TYPE_PNG))
            else:
                self.playPauseButton.SetBitmapLabel(wx.Bitmap(self.__state.main.config.root+"\\Images\\Pause.png", wx.BITMAP_TYPE_PNG))
            self.__state.OnTogglePlayPause()

    ##  Disables all buttons.
    def DisableFunctions(self):
        self.playPauseButton.Disable()
        self.stopButton.Disable()
        self.backwardButton.Disable()
        self.forwardButton.Disable()
        self.deleteButton.Disable()
        self.renameButton.Disable()
        self.slider.Disable()
        self.resetCamButton.Disable()

    ##  Enables all buttons.
    def EnableFunctions(self):
        self.playPauseButton.Enable()
        self.stopButton.Enable()
        self.backwardButton.Enable()
        self.forwardButton.Enable()
        self.deleteButton.Enable()
        self.renameButton.Enable()
        self.slider.Enable()
        self.resetCamButton.Enable()

    ## Resets the camera.
    def OnResetCam(self, event):
        self.__state.parent.ResetCamera(self.__state)
        self.widget.Render()